////////////////////////////////////////////////////////////////////////////////////////////////////
/// Copyright (c) 2009 - 2010 RacoonStudios
///
/// Permission is hereby granted, free of charge, to any person obtaining a copy of this
/// software and associated documentation files (the "Software"), to deal in the Software
/// without restriction, including without limitation the rights to use, copy, modify, merge,
/// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
/// to whom the Software is furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in all copies or
/// substantial portions of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
/// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
/// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
/// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
/// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
/// DEALINGS IN THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once
#ifndef scalar_h__
#define scalar_h__

#include "core/types.h"
#include "core/config.h"

typedef float scalar;

#define R_PI 3.14159265f
#define R_TINY 0.0000001f

#define R_LN2 0.693147181f




////////////////////////////////////////////////////////////////////////////////////////////////////
/// \fn	__forceinline scalar r_max(scalar a, scalar b)
///
/// \brief	Maximum function. 
///
/// \author	khaos
/// \date	04.12.2009
///
/// \param	a	a. 
/// \param	b	The. 
///
/// \return	. 
////////////////////////////////////////////////////////////////////////////////////////////////////
__forceinline scalar r_max(scalar a, scalar b)
{
	return (a < b) ? b : a;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \fn	__forceinline double r_max(double a, double b)
///
/// \brief	Maximum function. 
///
/// \author	khaos
/// \date	04.12.2009
///
/// \param	a	a. 
/// \param	b	The. 
///
/// \return	. 
////////////////////////////////////////////////////////////////////////////////////////////////////
__forceinline double r_max(double a, double b)
{
	return (a < b) ? b : a;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \fn	__forceinline int r_max(int a, int b)
///
/// \brief	Maximum function. 
///
/// \author	khaos
/// \date	04.12.2009
///
/// \param	a	a. 
/// \param	b	The. 
///
/// \return	. 
////////////////////////////////////////////////////////////////////////////////////////////////////
__forceinline int r_max(int a, int b)
{
	return (a < b) ? b : a;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \fn	__forceinline scalar r_min(scalar a, scalar b)
///
/// \brief	Minimum function. 
///
/// \author	khaos
/// \date	04.12.2009
///
/// \param	a	a. 
/// \param	b	The. 
///
/// \return	. 
////////////////////////////////////////////////////////////////////////////////////////////////////
__forceinline scalar r_min(scalar a, scalar b)
{
	return (a < b) ? a : b;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \fn	__forceinline double r_min(double a, double b)
///
/// \brief	Minimum function. 
///
/// \author	khaos
/// \date	04.12.2009
///
/// \param	a	a. 
/// \param	b	The. 
///
/// \return	. 
////////////////////////////////////////////////////////////////////////////////////////////////////
__forceinline double r_min(double a, double b)
{
	return (a < b) ? a : b;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \fn	__forceinline int r_min(int a, int b)
///
/// \brief	Minimum function. 
///
/// \author	khaos
/// \date	04.12.2009
///
/// \param	a	a. 
/// \param	b	The. 
///
/// \return	. 
////////////////////////////////////////////////////////////////////////////////////////////////////
__forceinline int r_min(int a, int b)
{
	return (a < b) ? a : b;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \fn	__forceinline scalar r_abs(scalar a)
///
/// \brief	Abs function. 
///
/// \author	khaos
/// \date	04.12.2009
///
/// \param	a	a. 
///
/// \return	. 
////////////////////////////////////////////////////////////////////////////////////////////////////
__forceinline scalar r_abs(scalar a)
{
	return (a < 0.0f) ? -a : a;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \fn	__forceinline double r_abs(double a)
///
/// \brief	Abs function. 
///
/// \author	khaos
/// \date	04.12.2009
///
/// \param	a	a. 
///
/// \return	. 
////////////////////////////////////////////////////////////////////////////////////////////////////
__forceinline double r_abs(double a)
{
	return (a < 0.0f) ? -a : a;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \fn	__forceinline int r_abs(int a)
///
/// \brief	Abs function. 
///
/// \author	khaos
/// \date	04.12.2009
///
/// \param	a	a. 
///
/// \return	. 
////////////////////////////////////////////////////////////////////////////////////////////////////
__forceinline int r_abs(int a)
{
	return (a < 0) ? -a : a;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \fn	__forceinline scalar r_sgn(scalar a)
///
/// \brief	Signum function. 
///
/// \author	khaos
/// \date	04.12.2009
///
/// \param	a	a. 
///
/// \return	. 
////////////////////////////////////////////////////////////////////////////////////////////////////
__forceinline scalar r_sgn(scalar a)
{
	(a < 0.0f) ? -1.0f : 1.0f;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \fn	__forceinline double r_sgn(double a)
///
/// \brief	Signum function. 
///
/// \author	khaos
/// \date	04.12.2009
///
/// \param	a	a. 
///
/// \return	. 
////////////////////////////////////////////////////////////////////////////////////////////////////
__forceinline double r_sgn(double a)
{
	(a < 0.0f) ? -1.0f : 1.0f;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \fn	__forceinline int r_sgn(int a)
///
/// \brief	Signum function. 
///
/// \author	khaos
/// \date	04.12.2009
///
/// \param	a	a. 
///
/// \return	. 
////////////////////////////////////////////////////////////////////////////////////////////////////
__forceinline int r_sgn(int a)
{
	(a < 0) ? -1 : 1;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \fn	__forceinline scalar r_sqrt(scalar s)
///
/// \brief	Sqrt. 
///
/// \author	khaos
/// \date	07.12.2009
///
/// \param	s	The. 
///
/// \return	. 
////////////////////////////////////////////////////////////////////////////////////////////////////
__forceinline scalar r_sqrt(scalar s)
{
	return sqrt(s);
}


__forceinline scalar r_log(scalar a)
{
	return logf(a);
}


__forceinline scalar r_log2(scalar x)
{
	return logf(x) / R_LN2;
}


__forceinline scalar r_exp(scalar a)
{
	return expf(a);
}


__forceinline scalar r_pow(scalar b, scalar e)
{
	return pow(b, e);
}


__forceinline scalar f_mod(scalar a, scalar b);


__forceinline scalar r_sin(scalar a)
{
#ifdef RE_USE_DX
	return XMScalarSin(a);
#else
	return sinf(a);
#endif
}


__forceinline scalar r_cos(scalar a)
{
#ifdef RE_USE_DX
	return XMScalarCos(a);
#else
	return cosf(a);
#endif
}

__forceinline scalar r_cot(scalar a)
{
	return 1.0f / tanf(a);
}


__forceinline scalar r_asin(scalar a)
{
#ifdef RE_USE_DX
	return XMScalarASin(a);
#else
	return asinf(a);
#endif
}


__forceinline scalar r_acos(scalar a)
{
#ifdef RE_USE_DX
	return XMScalarACos(a);
#else
	return acosf(a);
#endif
}


__forceinline scalar r_atan(scalar a)
{
	return atanf(a);
}


__forceinline scalar r_tan(scalar a)
{
	return tanf(a);
}


__forceinline scalar r_rand(scalar mi, scalar ma);


__forceinline scalar r_rand();

__forceinline scalar r_clamp(scalar a, scalar b, scalar c)
{
	if(a < b)			return b;
	else if(a > c)		return c;
	else				return a;
}

__forceinline int r_iclamp(int a, int b, int c)
{
	if(a < b)			return b;
	else if(a > c)		return c;
	else				return a;
}





#endif // scalar_h__